package cn.crex1.xiaomi.core.orm.mapper;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.crex1.xiaomi.core.orm.annotion.Query;
import cn.crex1.xiaomi.core.orm.annotion.ResultType;

public class MapperMethod {
	//缓存映射方法
	private Map<String, Object> methdodcached =new HashMap<>();
	//缓存sql
	private Map<String, Object> sqlvaluecache=new HashMap<>();
	//缓存参数列表
	private Map<String, List<Object>> argscache=new HashMap<>();
	//缓存返回值类型
	private Map<String, Object> resultcache=new HashMap<>();
	//缓存接口方法的返回值类型
	private Map<String, Object> methodResultCache=new HashMap<>();
	//当前执行方法的方法名
	private volatile String methodName;
	
	//解析接口类型的所有接口方法的信息
	protected void registryMapper(Class<?> clazz,Method method,Object...args) {
		if (clazz!=null && args!=null) {
			this.methodName=method.getName();
			Method[] methods = clazz.getMethods();
			for (int i = 0; i < methods.length; i++) {
				methdodcached.put(methods[i].getName(), methods[i]);
				//获取所有接口方法的sql
				initSql(methods[i]);
				//获取所有接口方法的返回值
				initResultType(methods[i]);
				
				initMethodResult(methods[i]);
			}
			//获取正在执行方法的映射参数
			initArgs(args);
		}
	}
	private void initSql(Method method) {
		if (method!=null) {
			if (method.isAnnotationPresent(Query.class)) {
				Query queryAnno= method.getAnnotation(Query.class);
				String sql = queryAnno.sql();
				sqlvaluecache.put(method.getName(), sql);
			}
		}
	}
	private void initResultType(Method method) {
		if (method!=null) {
			if (method.isAnnotationPresent(ResultType.class)) {
				ResultType resultAnno= method.getAnnotation(ResultType.class);
				String result = resultAnno.value();
				resultcache.put(method.getName(), result);
			}
		}
	}
	private void initArgs(Object...args) {
		List<Object> argsList=new ArrayList<>();
		if (args!=null) {
			int argslength = args.length;
			for (int i = 0; i < argslength; i++) {
				argsList.add(args[i]);
			}
			argscache.put(methodName, argsList);
		}
	}
	
	private void initMethodResult(Method method) {
		if (method!=null) {
			Type genericReturnType = method.getGenericReturnType();
			methodResultCache.put(method.getName(), genericReturnType.getTypeName());
		}
	}
	public Object getMethdodcached() {
		synchronized (methodName) {
			return  methdodcached.get(methodName);			
		}
	}
	public  String getSqlvaluecache() {
		synchronized (methodName) {
		return (String) sqlvaluecache.get(methodName);
		}
	}
	public String getResultcache() {
		synchronized (methodName) {
		return (String) resultcache.get(methodName);
		}
	}
	public String getMethodResultcache() {
		synchronized (methodName) {
		return (String) methodResultCache.get(methodName);
		}
	}
	public List<Object> getArgscache() {
		synchronized (methodName) {
		return argscache.get(methodName);
		}
	}
	public String getMethodName() {
		synchronized (methodName) {
		return methodName;
		}
	}
}
